home *** CD-ROM | disk | FTP | other *** search
-
- /* MODULE HTPasswd.c
- ** PASSWORD FILE ROUTINES
- **
- ** AUTHORS:
- ** AL Ari Luotonen luotonen@dxcern.cern.ch
- ** MD Mark Donszelmann duns@vxdeop.cern.ch
- **
- ** HISTORY:
- ** 7 Nov 93 MD free for crypt taken out (static data returned)
- **
- **
- ** BUGS:
- **
- **
- */
-
-
- #include <string.h>
-
- #include "HTUtils.h"
- #include "HTAAUtil.h" /* Common parts of AA */
- #include "HTAAFile.h" /* File routines */
- #include "HTPasswd.h" /* Implemented here */
- #include "tcp.h" /* FROMASCII() */
-
- extern char *crypt();
-
-
- PRIVATE char salt_chars [65] =
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
-
-
- /* PRIVATE next_rec()
- ** GO TO THE BEGINNING OF THE NEXT RECORD
- ** Otherwise like HTAAFile_nextRec() but
- ** does not handle continuation lines
- ** (because password file has none).
- ** ON ENTRY:
- ** fp is the password file from which records are read from.
- **
- ** ON EXIT:
- ** returns nothing. File read pointer is located at the beginning
- ** of the next record.
- */
- PRIVATE void next_rec ARGS1(FILE *, fp)
- {
- int ch = getc(fp);
-
- while (ch != EOF && ch != CR && ch != LF)
- ch = getc(fp); /* Skip until end-of-line */
-
- while (ch != EOF &&
- (ch == CR || ch == LF)) /*Skip carriage returns and linefeeds*/
- ch = getc(fp);
-
- if (ch != EOF)
- ungetc(ch, fp);
- }
-
-
- /* PUBLIC HTAA_encryptPasswd()
- ** ENCRYPT PASSWORD TO THE FORM THAT IT IS SAVED
- ** IN THE PASSWORD FILE.
- ** ON ENTRY:
- ** password is a string of arbitrary lenght.
- **
- ** ON EXIT:
- ** returns password in one-way encrypted form.
- **
- ** NOTE:
- ** Uses currently the C library function crypt(), which
- ** only accepts at most 8 characters long strings and produces
- ** always 13 characters long strings. This function is
- ** called repeatedly so that longer strings can be encrypted.
- ** This is of course not as safe as encrypting the entire
- ** string at once, but then again, we are not that paranoid
- ** about the security inside the machine.
- **
- */
- PUBLIC char *HTAA_encryptPasswd ARGS1(CONST char *, password)
- {
- char salt[3];
- char chunk[9];
- char *result;
- char *tmp;
- CONST char *cur = password;
- int len = strlen(password);
- extern time_t theTime;
- int random = (int)theTime; /* This is random enough */
-
- if (!(result = (char*)malloc(13*((strlen(password)+7)/8) + 1)))
- outofmem(__FILE__, "HTAA_encryptPasswd");
-
- *result = (char)0;
- while (len > 0) {
- salt[0] = salt_chars[random%64];
- salt[1] = salt_chars[(random/64)%64];
- salt[2] = (char)0;
-
- strncpy(chunk, cur, 8);
- chunk[8] = (char)0;
-
- tmp = crypt((char*)password, salt); /*crypt() doesn't change its args*/
- strcat(result, tmp);
-
- cur += 8;
- len -= 8;
- } /* while */
-
- return result;
- }
-
-
-
- /* PUBLIC HTAA_passwdMatch()
- ** VERIFY THE CORRECTNESS OF A GIVEN PASSWORD
- ** AGAINST A ONE-WAY ENCRYPTED FORM OF PASSWORD.
- ** ON ENTRY:
- ** password is cleartext password.
- ** encrypted is one-way encrypted password, as returned
- ** by function HTAA_encryptPasswd().
- ** This is typically read from the password
- ** file.
- **
- ** ON EXIT:
- ** returns YES, if password matches the encrypted one.
- ** NO, if not, or if either parameter is NULL.
- ** FIX:
- ** Only the length of original encrypted password is
- ** checked -- longer given passwords are accepted if
- ** common length is correct (but not shorter).
- ** This is to allow interoperation of servers and clients
- ** who have a hard-coded limit of 8 to password.
- */
- PUBLIC BOOL HTAA_passwdMatch ARGS2(CONST char *, password,
- CONST char *, encrypted)
- {
- char *result;
- int len;
- int status;
-
- if (!password || !encrypted)
- return NO;
-
- len = 13*((strlen(password)+7)/8);
- if (len < strlen(encrypted))
- return NO;
-
- if (!(result = (char*)malloc(len + 1)))
- outofmem(__FILE__, "HTAA_encryptPasswd");
-
- *result = (char)0;
- while (len > 0) {
- char salt[3];
- char chunk[9];
- CONST char *cur1 = password;
- CONST char *cur2 = encrypted;
- char *tmp;
-
- salt[0] = *cur2;
- salt[1] = *(cur2+1);
- salt[2] = (char)0;
-
- strncpy(chunk, cur1, 8);
- chunk[8] = (char)0;
-
- tmp = crypt((char*)password, salt);
- strcat(result, tmp);
-
- cur1 += 8;
- cur2 += 13;
- len -= 13;
- } /* while */
-
- status = strncmp(result, encrypted, strlen(encrypted));
-
- if (TRACE)
- fprintf(stderr,
- "%s `%s' (encrypted: `%s') with: `%s' => %s\n",
- "HTAA_passwdMatch: Matching password:",
- password, result, encrypted,
- (status==0 ? "OK" : "INCORRECT"));
-
- free(result);
-
- if (status==0)
- return YES;
- else
- return NO;
- }
-
-
- /* PUBLIC HTAAFile_readPasswdRec()
- ** READ A RECORD FROM THE PASSWORD FILE
- ** ON ENTRY:
- ** fp open password file
- ** out_username buffer to put the read username, must be at
- ** least MAX_USERNAME_LEN+1 characters long.
- ** out_passwd buffer to put the read password, must be at
- ** least MAX_PASSWORD_LEN+1 characters long.
- ** ON EXIT:
- ** returns EOF on end of file,
- ** otherwise the number of read fields
- ** (i.e. in a correct case returns 2).
- ** out_username contains the null-terminated read username.
- ** out_password contains the null-terminated read password.
- **
- ** FORMAT OF PASSWORD FILE:
- ** username:password:maybe real name or other stuff
- ** (may include even colons)
- **
- ** There may be whitespace (blanks or tabs) in the beginning and
- ** the end of each field. They are ignored.
- */
- PUBLIC int HTAAFile_readPasswdRec ARGS3(FILE *, fp,
- char *, out_username,
- char *, out_password)
- {
- char terminator;
-
- terminator = HTAAFile_readField(fp, out_username, MAX_USERNAME_LEN);
-
- if (terminator == EOF) { /* End of file */
- return EOF;
- }
- else if (terminator == CR || terminator == LF) { /* End of line */
- next_rec(fp);
- return 1;
- }
- else {
- HTAAFile_readField(fp, out_password, MAX_PASSWORD_LEN);
- next_rec(fp);
- return 2;
- }
- }
-
-
-
- /* PUBLIC HTAA_checkPassword()
- ** CHECK A USERNAME-PASSWORD PAIR
- ** ON ENTRY:
- ** username is a null-terminated string containing
- ** the client's username.
- ** password is a null-terminated string containing
- ** the client's corresponding password.
- ** filename is a null-terminated absolute filename
- ** for password file.
- ** If NULL or empty, the value of
- ** PASSWD_FILE is used.
- ** ON EXIT:
- ** returns YES, if the username-password pair was correct.
- ** NO, otherwise; also, if open fails.
- */
- PUBLIC BOOL HTAA_checkPassword ARGS3(CONST char *, username,
- CONST char *, password,
- CONST char *, filename)
- {
- FILE *fp = NULL;
- char user[MAX_USERNAME_LEN+1];
- char pw[MAX_PASSWORD_LEN+1];
- int status;
-
- if (filename && *filename) fp = fopen(filename,"r");
- else fp = fopen(PASSWD_FILE,"r");
-
- if (!fp) {
- if (TRACE) fprintf(stderr, "%s `%s'\n",
- "HTAA_checkPassword: Unable to open password file",
- (filename && *filename ? filename : PASSWD_FILE));
- return NO;
- }
- do {
- if (2 == (status = HTAAFile_readPasswdRec(fp,user,pw))) {
- if (TRACE)
- fprintf(stderr,
- "HTAAFile_validateUser: %s \"%s\" %s \"%s:%s\"\n",
- "Matching username:", username,
- "against passwd record:", user, pw);
- if (username && user && !strcmp(username,user)) {
- /* User's record found */
- if (pw) { /* So password is required for this user */
- if (!password ||
- !HTAA_passwdMatch(password,pw)) /* Check the password */
- status = EOF; /* If wrong, indicate it with EOF */
- }
- break; /* exit loop */
- } /* if username found */
- } /* if record is ok */
- } while (status != EOF);
-
- fclose(fp);
-
- if (TRACE) fprintf(stderr, "HTAAFile_checkPassword: (%s,%s) %scorrect\n",
- username, password, ((status != EOF) ? "" : "in"));
-
- if (status == EOF) return NO; /* We traversed to the end without luck */
- else return YES; /* The user was found */
- }
-
-